﻿'******************************************************
'******************************************************
'Application Title: Google Widget Editor
'version: 1.0
'Date: 01-02-2008
'Requirements: win2k or later
'Author: Andrew Pye
'Author Email: StretchMasterP@googlemail.com
'License: Released under GNU GENERAL PUBLIC LICENSE v3
'ToDo:
'Changes:Imports System.Text
'******************************************************
'******************************************************

Imports System.ComponentModel
Imports System.Xml
Imports GoogleWidgetEditor.ModulePrefs
Imports GoogleWidgetEditor.UserPref
Imports GoogleWidgetEditor.Content
Imports System.Text

Public Class Widget
    Implements IObjectName

#Region "Fields"
    Private _projectName As String = String.Empty
    Private _ModulePrefs As ModulePrefs = Nothing
    Private _UserPrefs As UserPrefs = Nothing
    Private _RequireLibs As RequireLibs = Nothing
    Private _content As ViewCollection = Nothing
    Private _Canvas As String = String.Empty
    Private _CodeSnippets As CodeSnippets = Nothing
    Private _Parent As Object = Nothing
    Private _IsDirty As Boolean = False
#End Region

#Region "Methods"
    ''' <summary>
    ''' Returns a cleaned project name for uploading file
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetCleanedProjectName() As String
        Return Me.ProjectName.Replace(" ", "")
    End Function
    Public Sub UnDirty()
        Me.IsDirty = False
    End Sub
    ''' <summary>
    ''' Imports a widget
    ''' </summary>
    ''' <remarks></remarks>
    Public Sub ImportWidget(ByVal FileName As String)
        Dim m_xmld As XmlDocument
        Dim m_nodelist As XmlNodeList
        Dim Tobj As XmlNode = Nothing

        m_xmld = New XmlDocument()
        'Load the Xml file

        m_xmld.Load(FileName)


        ' Dim reader As XmlReader = XmlReader.Create("c:\sound.xml")
        Dim TEnum As String = ""
        Debug.Print(m_xmld.Name)
        Tobj = m_xmld.ChildNodes(1).ChildNodes(0)

        With Tobj
            '=================
            'Read the ModPrefs
            '=================
            Me.ModulePrefs.Title = ReadXmlAttribute(Tobj, "title")
            Me.ProjectName = Me.ModulePrefs.Title
            Me.ModulePrefs.Directory_title = ReadXmlAttribute(Tobj, "directory_title")
            Me.ModulePrefs.Author = ReadXmlAttribute(Tobj, "author")
            Me.ModulePrefs.Author_email = ReadXmlAttribute(Tobj, "author_email")
            Me.ModulePrefs.Author_location = ReadXmlAttribute(Tobj, "author_location")
            Me.ModulePrefs.Author_link = ReadXmlAttribute(Tobj, "author_link")
            Me.ModulePrefs.Author_photo = ReadXmlAttribute(Tobj, "author_photo")
            TEnum = ReadXmlAttribute(Tobj, "category")
            If String.IsNullOrEmpty(TEnum) = False Then Me.ModulePrefs.Category = CType([Enum].Parse(GetType(enumGoogleCategorys), TEnum, True), enumGoogleCategorys)
            TEnum = ReadXmlAttribute(Tobj, "category2")
            If String.IsNullOrEmpty(TEnum) = False Then Me.ModulePrefs.Category2 = CType([Enum].Parse(GetType(enumGoogleCategorys), TEnum, True), enumGoogleCategorys)
            Me.ModulePrefs.Render_inline = ReadXmlAttribute(Tobj, "render_inline")
            Me.ModulePrefs.Title_url = ReadXmlAttribute(Tobj, "title_url")
            Me.ModulePrefs.Screenshot = ReadXmlAttribute(Tobj, "screenshot")
            Me.ModulePrefs.Thumbnail = ReadXmlAttribute(Tobj, "thumbnail")
            Me.ModulePrefs.Height = ReadXmlAttribute(Tobj, "height")
            Me.ModulePrefs.Description = ReadXmlAttribute(Tobj, "description")
            Me.ModulePrefs.Scrolling = ReadXmlAttribute(Tobj, "scrolling", 1)
            Me.ModulePrefs.Width = ReadXmlAttribute(Tobj, "width")
            If Val(Me.ModulePrefs.Width) = 0 Then Me.ModulePrefs.Width = 300
            If Val(Me.ModulePrefs.Height) = 0 Then Me.ModulePrefs.Height = 300
        End With

        '================
        'Read the Require
        '================
        m_nodelist = m_xmld.GetElementsByTagName("Require")
        For Each oNodes As XmlNode In m_nodelist
            Dim TData As String = ReadXmlAttribute(oNodes, "feature")
            Dim TOptional As String = ReadXmlAttribute(oNodes, "optional", 0)
            If TOptional = "" Then
                If String.IsNullOrEmpty(TData) = False Then Me.RequireLibs.Add(TData)
            Else
                If String.IsNullOrEmpty(TData) = False Then Me.RequireLibs.Add(TData, CType(TOptional, Boolean))
            End If
        Next

        '===================
        'Read the User Prefs
        '===================
        m_nodelist = m_xmld.GetElementsByTagName("UserPref")
        For Each oNodes As XmlNode In m_nodelist
            Dim o_UserPref As New UserPref
            o_UserPref.Name = ReadXmlAttribute(oNodes, "name")
            o_UserPref.Display_name = ReadXmlAttribute(oNodes, "display_name")
            o_UserPref.Default_value = ReadXmlAttribute(oNodes, "default_value")
            Dim datatype As String = ReadXmlAttribute(oNodes, "datatype")
            If String.IsNullOrEmpty(datatype) = False Then
                o_UserPref.Datatype = datatype
                'Add the enums
                For Each oXmlEnum As XmlNode In oNodes.ChildNodes
                    Dim oEnum As New EnumValue
                    oEnum.Display_value = ReadXmlAttribute(oXmlEnum, "display_value")
                    oEnum.Value = ReadXmlAttribute(oXmlEnum, "value")
                    If oEnum.Display_value = "" Then oEnum.Display_value = oEnum.Value
                    o_UserPref.Enums.Add(oEnum)
                Next

            End If
            Me.ModulePrefs.UserPrefs.Add(o_UserPref)
        Next

        '================
        'Read the Content
        '================
        m_nodelist = m_xmld.GetElementsByTagName("Content")
        For Each oNodes As XmlNode In m_nodelist
            Dim TContent As New Content
            TEnum = ReadXmlAttribute(oNodes, "view")
            If String.IsNullOrEmpty(TEnum) = False Then
                TContent.ViewType = TEnum
                TContent.Name = TEnum
            End If

            If TEnum = "" Then
                TEnum = ReadXmlAttribute(oNodes, "type")
                If String.IsNullOrEmpty(TEnum) = False Then TContent.Name = TEnum
            End If

            TContent.Description = ""
            TContent.Content = oNodes.InnerText 'CodeFormatter.FormatCode(oNodes.InnerText)
            Me.Content.Add(TContent)
        Next
        'Check to see if there is a project name
        If Me.ProjectName = "" Then
            Me.ProjectName = IO.Path.GetFileNameWithoutExtension(FileName)
        End If
    End Sub
    ''' <summary>
    ''' Read an Xml Attribute from a node
    ''' </summary>
    ''' <param name="Xnode"></param>
    ''' <param name="Name"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Private Function ReadXmlAttribute(ByVal Xnode As XmlNode, ByVal Name As String, Optional ByVal ReturnDataType As Integer = 0) As Object
        '0=string
        '1=boolean false
        '2=boolean true
        Try
            If Xnode.Attributes.ItemOf(Name) IsNot Nothing Then
                Return Xnode.Attributes.ItemOf(Name).Value
            Else
                Select Case ReturnDataType
                    Case 0
                        Return ""
                    Case 1
                        Return False
                    Case 2
                        Return True
                    Case Else
                        Return ""
                End Select

            End If
        Catch ex As Exception
            Select Case ReturnDataType
                Case 0
                    Return ""
                Case 1
                    Return False
                Case 2
                    Return True
                Case Else
                    Return ""
            End Select

        End Try
    End Function
    ''' <summary>
    ''' Save the Project
    ''' </summary>
    ''' <param name="filename">File name and path</param>
    ''' <remarks></remarks>
    Public Sub Save(ByVal filename As String)
        Dim mlSerializer As Xml.Serialization.XmlSerializer = New Xml.Serialization.XmlSerializer(GetType(Widget))
        Dim writer As IO.StringWriter = New IO.StringWriter()
        mlSerializer.Serialize(writer, Me)
        My.Computer.FileSystem.WriteAllText(filename, writer.ToString, False, Global.System.Text.Encoding.Default)
    End Sub
    Public Sub AddRequireLibs(ByVal Feature As String)
        If Me.RequireLibs Is Nothing Then Me.RequireLibs = New RequireLibs
        With Me.RequireLibs
            .Add(Feature)
        End With
    End Sub
    Public Sub SetDirty()
        If Me.Parent IsNot Nothing Then Me.IsDirty = True
    End Sub
    ''' <summary>
    ''' Build the xml String
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function BuildXml(Optional ByVal BuildView As String = "") As String
        Dim TRequireLibs As String = String.Empty

        Dim sb As StringBuilder = New StringBuilder
        sb.AppendLine("<?xml version='1.0' encoding='UTF-8'?>")
        '======
        'Module
        '======
        sb.AppendLine("<Module>")

        '============
        'Require libs
        '============
        If Me.RequireLibs IsNot Nothing Then
            TRequireLibs = Me.RequireLibs.BuildXml
            'sb.AppendLine(Me.RequireLibs.BuildXml)
        End If
        '============
        'Module prefs
        '============
        If Me.ModulePrefs IsNot Nothing Then
            sb.AppendLine(Me.ModulePrefs.BuildXml(TRequireLibs))
        End If
        ''============
        ''Require libs
        ''============
        'If Me.RequireLibs IsNot Nothing Then
        '    sb.Insert(-1, Me.RequireLibs.BuildXml)
        '    'sb.AppendLine(Me.RequireLibs.BuildXml)
        'End If

        '=======
        'Content
        '=======
        'Need top fimd and replace tags

        sb.AppendLine(FindReplaceTags(Me.Content.BuildXml(BuildView)))
        sb.AppendLine("</Module>")

        Return sb.ToString
    End Function
    Private Function FindReplaceTags(ByVal Code As String) As String
        Dim oTag As New MPTools.Strings.TagExtractor
        Dim Tags() As String = oTag.ExtractTags(Code, "<%", "%>", True)
        For Each Tag As String In Tags
            Dim CodeSnip As CodeSnippet = Me.Code_Snippets.Item(Tag)
            If CodeSnip IsNot Nothing Then
                Code = Code.Replace("<%" & Tag & "%>", CodeSnip.Code)
            End If
        Next
        Return Code
    End Function
    'Public Function AddUserPref(ByVal Name As String, ByVal Display_name As String, ByVal Default_value As String, ByVal Datatype As UserPref.EnumDataType) As UserPref
    '    If Me._UserPrefs Is Nothing Then Me._UserPrefs = New UserPrefs()
    '    Return Me.UserPrefs.Add(Name, Display_name, Default_value, Datatype)
    'End Function
    Public Sub SetModPrefs(Optional ByVal Author As String = "", _
    Optional ByVal Author_email As String = "", _
    Optional ByVal Author_affiliation As String = "", _
    Optional ByVal Screenshot As String = "", _
    Optional ByVal Thumbnail As String = "", _
    Optional ByVal Category As String = "", _
    Optional ByVal Description As String = "", _
    Optional ByVal Render_inline As String = "", _
    Optional ByVal Height As String = "", _
    Optional ByVal Width As String = "", _
    Optional ByVal Scaling As String = "")

        If Me.ModulePrefs Is Nothing Then Me.ModulePrefs = New ModulePrefs
        With Me.ModulePrefs
            .Author = Author
            .Author_email = Author_email
            .Author_affiliation = Author_affiliation
            .Screenshot = Screenshot
            .Thumbnail = Thumbnail
            .Category = Category
            .Description = Description
            .Render_inline = Render_inline
            .Height = Height
            .Width = Width
            .Scaling = Scaling
        End With

    End Sub
#End Region

#Region "Constructor"
    Public Sub New()
        'Set Up
        ModulePrefs = New ModulePrefs
        ModulePrefs.SetParent(Me)
        Code_Snippets = New CodeSnippets
        Code_Snippets.SetParent(Me)
        RequireLibs = New RequireLibs
        RequireLibs.SetParent(Me)
        Content = New ViewCollection
        Content.SetParent(Me)
    End Sub
    Protected Overrides Sub Finalize()
        MyBase.Finalize()
        'Clean Up
        ModulePrefs = Nothing
        Code_Snippets = Nothing
        RequireLibs = Nothing
        Content = Nothing
    End Sub
#End Region

#Region "Properties"
    <Browsable(False)> _
    Public Property IsDirty() As Boolean
        Get
            Return _IsDirty
        End Get
        Set(ByVal value As Boolean)
            _IsDirty = value
        End Set
    End Property
    Protected ReadOnly Property Parent() As Object Implements IObjectName.Parent
        Get
            Return _Parent
        End Get
    End Property
    Public Sub SetParent(ByVal ParentObject As Object) Implements IObjectName.SetParent
        _Parent = ParentObject
    End Sub
    <BrowsableAttribute(False)> _
    Public Property Code_Snippets() As CodeSnippets
        Get
            Return _CodeSnippets
        End Get
        Set(ByVal value As CodeSnippets)
            _CodeSnippets = value
        End Set
    End Property
    <BrowsableAttribute(False)> _
    Public Property Content() As ViewCollection
        Get
            Return _content
        End Get
        Set(ByVal value As ViewCollection)
            _content = value
        End Set
    End Property
    <BrowsableAttribute(False)> _
    Public Property ModulePrefs() As ModulePrefs
        Get
            Return _ModulePrefs
        End Get
        Set(ByVal value As ModulePrefs)
            _ModulePrefs = value
        End Set
    End Property
    Public Property ProjectName() As String
        Get
            Return _projectName
        End Get
        Set(ByVal value As String)
            _projectName = value
            Me.SetDirty()
        End Set
    End Property
    <BrowsableAttribute(False)> _
    Public Property RequireLibs() As RequireLibs
        Get
            Return _RequireLibs
        End Get
        Set(ByVal value As RequireLibs)
            _RequireLibs = value
        End Set
    End Property
    <BrowsableAttribute(False)> _
    Public ReadOnly Property ObjectName() As String Implements IObjectName.ObjectName
        Get
            Return Me.ProjectName
        End Get
    End Property
#End Region
End Class
